package com.hddf.project.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import org.apache.commons.io.output.ByteArrayOutputStream;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;

import com.artofsolving.jodconverter.DocumentConverter;
import com.artofsolving.jodconverter.openoffice.connection.OpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.connection.SocketOpenOfficeConnection;
import com.artofsolving.jodconverter.openoffice.converter.OpenOfficeDocumentConverter;

/**
 * 通用工具类. 编写时间:2013年.
 * 
 * @author YY
 * 
 */

@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
public class O {
	private static Log logger = LogFactory.getLog(O.class);

	public static String clazzMethod() {
		String clazz = Thread.currentThread().getStackTrace()[3].getClassName();
		String method = Thread.currentThread().getStackTrace()[3].getMethodName();
		return "@" + clazz + "_" + method;
	}

	public static void p(Object obj) {
		log(getSdf("HM").format(new Date()) + "输出:" + obj);
	}

	private static void log(String logs) {
		logger.info(logs);
	}

	/**
	 * 操作失败
	 * 
	 * @param logs
	 *            日志记录内容,例:
	 * @param e
	 *            异常内容
	 */
	private static void log(String logs, Exception e) {
		logger.error("@错    " + getSdf("C").format(new Date()) + logs, e);
	}

	/**
	 * 生成随机数
	 */
	public static int random(int inum) {
		int rit = 0;
		rit = (int) (Math.random() * inum);
		return rit;
	}

	/**
	 * 验证权限
	 * 
	 * @param url
	 * @return
	 */
	public static boolean ckauth(String url) {
		boolean bn = false;
		if (ckSt(url)) {
			int i = url.indexOf("_");
			if (i != -1) {
				url = url.substring(0, i);
				String[] lsqx = XmlUtil.conf("AUTH").split(",");
				for (String str : lsqx) {
					if (str.equals(url))
						bn = true;
				}
			}
		}
		return bn;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 时间工具
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 时间格式化
	 * 
	 * @param str
	 *            S:yyyy-MM-dd; L:yyyy-MM-dd HH:mm:ss; C:yyyy-MM-dd
	 *            HH:mm:ss.SSS; YM:yyyy-MM; yyyyMMddHHmmssSSS
	 * @return
	 */
	public static SimpleDateFormat getSdf(String str) {
		SimpleDateFormat sdf = null;
		try {
			if (str.equals("S")) {
				sdf = new SimpleDateFormat("yyyy-MM-dd");
			} else if (str.equals("LNS")) {
				sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
			} else if (str.equals("HM")) {
				sdf = new SimpleDateFormat("HH:mm");
			} else if (str.equals("DHM")) {
				sdf = new SimpleDateFormat("dd HH:mm");
			} else if (str.equals("L")) {
				sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			} else if (str.equals("C")) {
				sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
			} else if (str.equals("YM")) {
				sdf = new SimpleDateFormat("yyyy-MM");
			} else if (str.equals("D")) {
				sdf = new SimpleDateFormat("dd");
			} else if (str.equals("M")) {
				sdf = new SimpleDateFormat("MM");
			} else {
				sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return sdf;
	}

	/**
	 * 获取时间，String类型,例：201212121212。 * @return
	 */
	public static String getTimestamp2() {
		return getSdf("str").format(new Date());
	}

	/**
	 * 获取当前时间，String类型，例：2013-07-29 10:10:10
	 */
	public static String getTimestamp3() {
		return getSdf("L").format(new Date());
	}

	/**
	 * 时间操作,设置时间
	 * 
	 * @param date
	 *            ;new Date();
	 * @param cnum
	 *            ;0:设置年,1:设置月,2设置号,3:设置星期,4:设置时,5:设置分,6:设置秒
	 * @param num
	 * @return
	 */
	public static Date setCalendar(Date date, int cnum, int num) {
		Calendar cr = Calendar.getInstance();
		cr.setTime(date);
		switch (cnum) {
		case 0:
			cr.set(Calendar.YEAR, num);
			break;
		case 1:
			cr.set(Calendar.MONTH, num);
			break;
		case 2:
			cr.set(Calendar.DAY_OF_MONTH, num);
			break;
		case 3:
			cr.set(Calendar.DAY_OF_WEEK, num);
			break;
		case 4:
			cr.set(Calendar.HOUR_OF_DAY, num);
			break;
		case 5:
			cr.set(Calendar.MINUTE, num);
			break;
		case 6:
			cr.set(Calendar.SECOND, num);
			break;
		default:
			break;
		}
		date = cr.getTime();
		return date;
	}

	/**
	 * 获取时间
	 * 
	 * @param date
	 *            ;
	 * @param cnum
	 *            ;0:获取年,1:获取月,2获取号,3:获取星期,4:获取时,5:获取分,6:获取秒
	 * @return
	 */
	public static int getCalendar(Date date, int cnum) {
		int i = 0;
		Calendar calendar = new GregorianCalendar();
		calendar.setTime(date);
		switch (cnum) {
		case 0:
			i = calendar.get(Calendar.YEAR);
			break;
		case 1:
			i = calendar.get(Calendar.MONTH);
			break;
		case 2:
			i = calendar.get(Calendar.DAY_OF_MONTH);
			break;
		case 3:
			i = calendar.get(Calendar.DAY_OF_WEEK);
			break;
		case 4:
			i = calendar.get(Calendar.HOUR_OF_DAY);
			break;
		case 5:
			i = calendar.get(Calendar.MINUTE);
			break;
		case 6:
			i = calendar.get(Calendar.SECOND);
			break;
		default:
			break;
		}
		return i;
	}

	/**
	 * 获取当前最精确时间
	 * 
	 * @return 如:2013-05-09 16:38:19.912
	 */
	public static Timestamp getTimestamp() {
		return new Timestamp(System.currentTimeMillis());
	}

	/**
	 * 转换非精确时间,使返回带时分秒的准确时间
	 * 
	 * @param stTe
	 *            +00:00:01;
	 * @param edTe
	 *            +23:59:59;
	 * @return [0]开始时间;[1]结束时间
	 */
	public static String[] cnTe(String stTe, String edTe) {
		String[] rte = new String[2];
		rte[0] = stTe + " 00:00:01";
		rte[1] = edTe + " 23:59:59";
		return rte;
	}

	/**
	 * 
	 * @param te
	 * @return
	 */
	public static String[] cnTe(String te) {
		String[] rte = new String[2];
		try {
			String stTe = te + " " + XmlUtil.conf("BLTE");
			Date date = getSdf("S").parse(te);
			Date tde = setCalendar(date, 2, getCalendar(date, 2) + 1);
			String edTe = getSdf("S").format(tde);
			rte[0] = stTe;
			rte[1] = edTe + " " + XmlUtil.conf("BLTE");
		} catch (Exception e) {
			log("时间转换失败,错误为:", e);
		}
		return rte;
	}

	/**
	 * 查看时间差值
	 * 
	 * @param cnum
	 *            0:查看天差值;1:查看时差值;2:查看分差值3:查看秒差值
	 * @param cst
	 *            S:精确到天; L:精确到秒;
	 * @param stTe
	 *            起始时间
	 * @param edTe
	 *            结束时间
	 * @return
	 */
	public static Long chaTime(Integer cnum, String cst, String stTe, String edTe) {
		Long rst = cnLg(0);
		try {
			Date st = getSdf(cst).parse(stTe);
			Date ed = getSdf(cst).parse(edTe);
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(st);
			long stTeL = calendar.getTimeInMillis();
			calendar.setTime(ed);
			long edTeL = calendar.getTimeInMillis();

			switch (cnum) {
			case 0:
				rst = ((stTeL - edTeL) / (1000 * 60 * 60 * 24));
				break;
			case 1:
				rst = ((stTeL - edTeL) / (1000 * 60 * 60));
				break;
			case 2:
				rst = ((stTeL - edTeL) / (1000 * 60));
				break;
			case 3:
				rst = ((stTeL - edTeL) / (1000));
				break;
			default:
				break;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return rst;
	}

	/**
	 * 获取一个月的最后一天
	 * 
	 * @param date
	 *            Date类型.
	 * @return
	 */
	public static Date lastDayOfMonth(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.roll(Calendar.DAY_OF_MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 获取一个月的最后一天
	 * 
	 * @param date
	 *            字符串 :时间精确度大于或等于天,如:2013-05-22
	 * @return
	 * @throws ParseException
	 */
	public static Date lastDayOfMonth(String date) throws ParseException {
		Date de = getSdf("S").parse(date);
		Calendar cal = Calendar.getInstance();
		cal.setTime(de);
		cal.set(Calendar.DAY_OF_MONTH, 1);
		cal.roll(Calendar.DAY_OF_MONTH, -1);
		return cal.getTime();
	}

	/**
	 * 时间比较
	 * 
	 * @param cst
	 *            精确度 S:精确为天; L:精确到分钟
	 * @param stTe
	 *            开始时间
	 * @param edTe
	 *            结束时间
	 * @return stTe<=edTe 时为ture 其余为false
	 */
	public static boolean comparisonTime(String cst, String stTe, String edTe) {
		boolean bn = true;
		try {
			Date st = getSdf(cst).parse(stTe);
			Date ed = getSdf(cst).parse(edTe);
			int result = st.compareTo(ed);
			if (result == 1) {
				bn = false;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bn;
	}

	/**
	 * 转换数据库格式的时间
	 * 
	 * @param cst
	 *            时间格式,如:yyyy-MM-dd
	 * @param dateString
	 *            需要转换的时间.
	 * @return
	 * @throws java.lang.Exception
	 */
	public static Timestamp cnSqlDate(String time) throws java.lang.Exception {
		Timestamp ts = new Timestamp(System.currentTimeMillis());
		try {
			ts = Timestamp.valueOf(time);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return ts;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 基础数据判断 工具
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 判断String是否为空
	 * 
	 * @param ot
	 *            所要判断的内容
	 * @return True:不为空;Flase:为空
	 */
	public static boolean ckSt(Object ot) {
		String str = String.valueOf(ot);
		if (str != null && str != "" && str.length() > 0 && !str.equals("null")) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 
	 * @param obj
	 * @param length
	 * @param bqct
	 * @return
	 */
	public static String cnSt(Object obj, Integer size) {
		String rs = "";
		String rst = cnSt(obj);
		StringBuffer sb = new StringBuffer(rst);

		for (int i = (rst.getBytes().length / 2); i < size; i++) {
			sb.append("　");
		}

		return sb.toString();
	}

	/**
	 * 判断String是否为大于所给数据长度的字符串
	 * 
	 * @param object
	 *            所要判断的内容
	 * @param length
	 *            要求的数据长度
	 * @return
	 */
	public static boolean ckSt(Object object, int length) {
		String str = String.valueOf(object);
		if (str != null && str != "" && str.length() > length) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断Object是否为数字
	 * 
	 * @param ot
	 * @return;Ture:数字;False:非数字
	 */
	public static boolean ckNm(Object ot) {
		String str = String.valueOf(ot);
		if (ckSt(str)) {
			return str.matches("^[-+]?(([0-9]+)([.]([0-9]+))?|([.]([0-9]+))?)$");
		} else {
			return false;
		}
	}

	/**
	 * 判断集合是否为空
	 * 
	 * @param olt
	 * @return;True:not null;False:null
	 */

	public static boolean ckLt(List lto) {
		if (lto != null && lto.size() > 0 && !lto.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 判断Object是否为浮点型数据
	 * 
	 * @param ot
	 * @return;True:浮点型数据;Flase:非浮点型数据
	 */
	public static boolean ckFt(Object ot) {
		String str = String.valueOf(ot);
		if (ckSt(str)) {
			Pattern pn = Pattern.compile("[0-9]*(\\.?)[0-9]*");
			return pn.matcher(str).matches();
		} else {
			return false;
		}
	}

	/**
	 * 判断字符串是否在段落中
	 * 
	 * @param str
	 *            1,2,3,4,5
	 * @param ist
	 *            1
	 * @return
	 */
	public static boolean ckInStr(Object str, Object ist) {
		boolean bn = false;
		if (ckSt(str) && ckSt(ist)) {
			if (("," + cnSt(str) + ",").indexOf(("," + cnSt(ist) + ",")) != -1) {
				bn = true;
			}
		}
		return bn;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 转换基础数据
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 字符串的转换
	 * 
	 * @param str
	 * @return;如果str不为空,str;如果str为空, "";
	 */
	public static String cnSt(Object ot) {
		String str = String.valueOf(ot).trim();
		if (ckSt(str)) {
			return str;
		} else {
			return "";
		}
	}

	/**
	 * 将Object类型转换成浮点型数据
	 * 
	 * @param ot
	 * @return;ot为空时:return 0.0;
	 */
	public static Float cnFt(Object ot) {
		String str = String.valueOf(ot);
		if (ckSt(str)) {
			try {
				return Float.parseFloat(str);
			} catch (Exception e) {
				return Float.parseFloat("0.0");
			}
		} else {
			return Float.parseFloat("0.0");
		}
	}

	/**
	 * 将Object类型转换成double型数据
	 * 
	 * @param ot
	 * @return;ot为空时:return 0.0;
	 */
	public static Double cnDe(Object ot) {
		String str = String.valueOf(ot);
		if (ckSt(str)) {
			try {
				return Double.parseDouble(str);
			} catch (Exception e) {
				return Double.parseDouble("0.00");
			}
		} else {
			return Double.parseDouble("0.00");
		}
	}

	/**
	 * 将Object类型转换成Int数据
	 * 
	 * @param ot
	 * @return;ot为空时:return 0.0;
	 */
	public static Integer cnIt(Object ot) {
		String str = String.valueOf(ot);
		if (ckSt(str)) {
			if (ckNm(str) || ckNm(str)) {
				return Integer.parseInt(cnSt(formateNumber("0", str)));
			} else {
				return Integer.parseInt("0");
			}
		} else {
			return Integer.parseInt("0");
		}
	}

	/**
	 * 将Object转换成long类型.
	 * 
	 * @param obj
	 * @return
	 */
	public static Long cnLg(Object obj) {
		String str = String.valueOf(obj);
		if (ckSt(str)) {
			if (ckNm(str) || ckNm(str)) {
				return Long.parseLong(str);
			} else {
				return Long.parseLong("0");
			}
		} else {
			return Long.parseLong("0");
		}
	}

	/**
	 * 将String类型装换成lto类型
	 * 
	 * @param str
	 *            需要转换的数据需要以逗号尽心分割 格式如下:Hello,World,Test
	 * @return
	 */
	public static List<Object> cnLt(String str) {
		List<Object> lto = new ArrayList<Object>();
		if (ckSt(str)) {
			String[] sts = str.split(",");
			for (String s : sts) {
				lto.add(s);
			}
		}
		return lto;
	}

	/**
	 * 格式化数字(基本用于金钱)
	 * 
	 * @param cst
	 *            格式化类型,如: 0; 0.0; 0.00
	 * @param obj
	 *            所需格式化的数字.
	 * @return
	 */
	public static String formateNumber(String cst, Object obj) {
		String str = "";
		try {
			if (ckSt(cst))
				str = new DecimalFormat(cst).format(cnFt(obj));
			else
				str = new DecimalFormat("###,###,###,###.###").format(cnFt(obj));
		} catch (Exception e) {
			log("O.java_格式化数字,@param cst=" + cst + ",@param obj=" + obj + ", @return=" + str, e);
		}

		return str;
	}

	public static Float formateNumber(Integer num, Object obj) {
		String str = "";
		try {
			if (num == 0)
				str = new DecimalFormat("0").format(cnFt(obj));
			if (num == 1)
				str = new DecimalFormat("0.0").format(cnFt(obj));
			if (num == 2)
				str = new DecimalFormat("0.00").format(cnFt(obj));
		} catch (Exception e) {
			log("O.java_格式化数字,@param num=" + num + ",@param obj=" + obj + ", @return=" + str, e);
		}

		return cnFt(str);
	}

	/**
	 * 截取字符串
	 * 
	 * @param obj
	 *            100001;
	 * @return 10000
	 */
	public static String subStr(Object obj) {
		if (ckSt(obj)) {
			obj = cnSt(obj).substring(0, cnSt(obj).length() - 1);
		}
		return cnSt(obj);
	}

	/**
	 * 冒泡排序
	 * 
	 * @param scores
	 * @return
	 */
	public static Float[] sortFt(Float[] scores) {
		// 定义临时变量
		float temp = 0.0f;
		// 进行冒泡排序：i控制比较多少轮，j控制每轮比较多少次
		for (int i = 0; i < scores.length - 1; i++) {
			for (int j = 0; j < scores.length - 1 - i; j++) {
				if (scores[j] > scores[j + 1]) {
					temp = scores[j];
					scores[j] = scores[j + 1];
					scores[j + 1] = temp;
				}
			}
		}
		return scores;
	}

	/**
	 * 将集合中相同的数据进行分组成单个集合,存放在List<Object>中
	 * 
	 * @param sglo
	 * @return
	 */
	public static List<Object> cnLt(List<String> sglo) {
		List<Object> lto = new ArrayList<Object>();
		List<String> sgslo = new ArrayList<String>();
		for (int i = 0; i < sglo.size(); i++) {
			if (sgslo.indexOf(sglo.get(i)) != -1) {
				List<String> zsglo = (List<String>) lto.get(sgslo.indexOf(sglo.get(i)));
				zsglo.add(sglo.get(i));
				lto.set(sgslo.indexOf(sglo.get(i)), zsglo);
			} else {
				List<String> zsglo = new ArrayList<String>();
				sgslo.add(sglo.get(i));
				zsglo.add(sglo.get(i));
				lto.add(zsglo);
			}
		}
		return lto;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// HQL语句生成.
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 单个条件生成HQL语句 用于字符型模糊查询
	 * 
	 * @param hq
	 *            实体对应字段 例:userName(用户名)
	 * @param val
	 *            实体对应数据 例:张三
	 * @return and userName like '%张三%'
	 */
	public static String csl(String hq, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and " + hq + " like '%" + val + "%'";
		} catch (Exception e) {
			log("O.java_单个条件生成HQL语句 用于字符型模糊查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}
		return rHql;
	}

	/**
	 * 单个条件生成HQL语句 字符串型 精确查询
	 * 
	 * @param hq
	 *            实体对应字段 例:userName(用户名)
	 * @param val
	 *            实体对应数据 例:张三
	 * @return 例: and userName = '张三'
	 */
	public static String ccs(String hq, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and " + hq + " = '" + val + "'";
		} catch (Exception e) {
			log("O.java_个条件生成HQL语句 字符串型 精确查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}

		return rHql;
	}

	/**
	 * In 单个条件生成HQL语句 字符串型 精确查询
	 * 
	 * @param hq
	 *            实体对应字段 例:id(用户ID)
	 * @param val
	 *            实体对应数据 例:1,2,3
	 * @return 例: and id in (1,2,3)
	 */
	public static String cci(String hq, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and " + hq + " in (" + val + ")";
		} catch (Exception e) {
			log("O.java_个条件生成HQL语句 字符串型 精确查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}

		return rHql;
	}

	/**
	 * In 单个条件生成HQL语句 字符串型 精确查询
	 * 
	 * @param hq
	 *            实体对应字段 例:id(用户ID)
	 * @param val
	 *            实体对应数据 例:1,2,3
	 * @return 例: and id not in (1,2,3)
	 */
	public static String ccni(String hq, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and " + hq + " not in (" + val + ")";
		} catch (Exception e) {
			log("O.java_个条件生成HQL语句 字符串型 精确查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}

		return rHql;
	}

	/**
	 * Like
	 * 
	 * @param hq
	 * @param val
	 * @return
	 */
	public static String ccl(String hq, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and " + hq + " like '%" + val + "%'";
		} catch (Exception e) {
			log("O.java_个条件生成HQL语句 字符串型 精确查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}

		return rHql;
	}

	public static String cco(String hqo, String hqt, String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " and (" + hqo + " like '%" + val + "%' or " + hqt + " like '%" + val + "%')";
		} catch (Exception e) {
			log("cco准换错误,错误原因", e);
		}

		return rHql;
	}

	/**
	 * 单个条件生成HQL语句 数字型 精确查询
	 * 
	 * @param hq
	 *            实体对应字段 例:age(年龄)
	 * @param val
	 *            实体对应数据 例:18
	 * @return 例: and age = 18
	 */
	public static String ccs(String hq, Number val) {
		String rHql = "";
		try {
			if (ckNm(val))
				rHql = " and " + hq + " = " + val;
		} catch (Exception e) {
			log("O.java_单个条件生成HQL语句 数字型 精确查询,@param hq=" + hq + ",@param val=" + val + ", @return=" + rHql, e);
		}
		return rHql;
	}

	/**
	 * 生成 group by + val
	 * 
	 * @param val
	 * @return
	 */
	public static String ccs(String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " group by " + val;
		} catch (Exception e) {
			log("生成 group by + val失败,错误为:", e);
		}
		return rHql;
	}

	/**
	 * 生成Order by 语句
	 * 
	 * @param val
	 *            升序
	 * 
	 * @return
	 */
	public static String coa(String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " order by " + val + " asc";
		} catch (Exception e) {
			log("生成 order by + val失败,错误为:", e);
		}
		return rHql;
	}

	/**
	 * 生成Order by 语句
	 * 
	 * @param val
	 *            降序
	 * @return
	 */
	public static String cod(String val) {
		String rHql = "";
		try {
			if (ckSt(val))
				rHql = " order by " + val + " desc";
		} catch (Exception e) {
			log("生成 order by + val失败,错误为:", e);
		}
		return rHql;
	}

	/**
	 * 多条件生成HQL语句,用于时间操作
	 * 
	 * @param hq
	 *            实体对应字段 例:cute(创建时间)
	 * @param stTe
	 *            实体对应起始时间数据 例:"2012-01-25" 或 null
	 * @param edTe
	 *            实体对应结束时间数据 例:"2012-08-15" 或 null
	 * @return cute between '2012-01-25' and '2012-08-15' 或 cute>='2012-01-25' 或
	 *         cute<='2012-08-15'
	 */
	public static String ccs(String hq, String stTe, String edTe) {
		String rHql = "";
		try {
			if (ckSt(stTe) || ckSt(edTe)) {
				rHql = " and (";
				if (ckSt(stTe) && !ckSt(edTe)) {
					rHql += hq + ">='" + stTe + "')";
				}
				if (!ckSt(stTe) && ckSt(edTe)) {
					rHql += hq + "<='" + edTe + "')";
				}
				if (ckSt(stTe) && ckSt(edTe)) {
					rHql += hq + " between '" + stTe + "' and '" + edTe + "')";
				}
			}
		} catch (Exception e) {
			log("O.java_多条件生成HQL语句,用于时间操作,@param hq=" + hq + ",@param stTe=" + stTe + "@param edTe=" + edTe + ", @return=" + rHql,
					e);
		}

		return rHql;
	}

	/**
	 * 多条件生成HQL语句,用于数字操作
	 * 
	 * @param hq
	 *            实体对应字段 例:age(创建时间)
	 * @param stNm
	 *            实体对应起始时间数据 例:20 或 null
	 * @param edNm
	 *            实体对应结束时间数据 例:50 或 null
	 * @return cute between 20 and '50' 或 cute>=20 或 cute<='50'
	 */
	public static String ccst(String hq, Number stNm, Number edNm) {
		String rHql = "";
		try {
			if (ckSt(stNm) || ckSt(edNm)) {
				rHql = " and (";
				if (ckSt(stNm) && !ckSt(edNm))
					rHql += hq + ">=" + stNm + ")";

				if (!ckSt(stNm) && ckSt(edNm))
					rHql += hq + "<=" + edNm + ")";

				if (ckSt(stNm) && ckSt(edNm))
					rHql += hq + " between " + stNm + " and " + edNm + ")";
			}
		} catch (Exception e) {
			log("O.java_多条件生成HQL语句,用于数字操作,@param hq=" + hq + ",@param stNm=" + stNm + "@param edNm=" + edNm + ", @return=" + rHql,
					e);
		}

		return rHql;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 对文件操作
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 删除文件夹
	 * 
	 * @param folderPath
	 *            文件夹完整绝对路径
	 */
	public static boolean delFolder(String sPath) {
		try {
			boolean flag = false;
			File file = new File(sPath);
			// 判断目录或文件是否存在
			if (!file.exists()) { // 不存在返回 false
				return flag;
			} else {
				// 判断是否为文件
				if (file.isFile()) { // 为文件时调用删除文件方法
					return deleteFile(sPath);
				} else { // 为目录时调用删除目录方法
					return deleteDirectory(sPath);
				}
			}
		} catch (Exception e) {
			log("O.java_删除文件夹,@param folderPath=" + sPath, e);
			return false;
		}

	}

	public static boolean deleteFile(String sPath) {
		boolean flag = false;
		File file = new File(sPath);
		// 路径为文件且不为空则进行删除
		if (file.isFile() && file.exists()) {
			file.delete();
			flag = true;
		}
		return flag;
	}

	/**
	 * 删除目录（文件夹）以及目录下的文件
	 * 
	 * @param sPath
	 *            被删除目录的文件路径
	 * @return 目录删除成功返回true，否则返回false
	 */
	public static boolean deleteDirectory(String sPath) {
		// 如果sPath不以文件分隔符结尾，自动添加文件分隔符
		if (!sPath.endsWith(File.separator)) {
			sPath = sPath + File.separator;
		}
		File dirFile = new File(sPath);
		// 如果dir对应的文件不存在，或者不是一个目录，则退出
		if (!dirFile.exists() || !dirFile.isDirectory()) {
			return false;
		}
		boolean flag = true;
		// 删除文件夹下的所有文件(包括子目录)
		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			// 删除子文件
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag)
					break;
			} // 删除子目录
			else {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag)
					break;
			}
		}
		if (!flag)
			return false;
		// 删除当前目录
		if (dirFile.delete()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 删除指定文件夹下所有文件
	 * 
	 * @param path
	 *            文件夹完整绝对路径
	 * @return
	 */
	public static boolean delAllFile(String path) {
		boolean flag = false;
		try {
			File file = new File(path);
			if (!file.exists()) {
				return flag;
			}
			if (!file.isDirectory()) {
				return flag;
			}
			String[] tempList = file.list();
			File temp = null;
			for (int i = 0; i < tempList.length; i++) {
				if (path.endsWith(File.separator))
					temp = new File(path + tempList[i]);
				else
					temp = new File(path + File.separator + tempList[i]);

				if (temp.isFile())
					temp.delete();

				if (temp.isDirectory()) {
					delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
					delFolder(path + "/" + tempList[i]);// 再删除空文件夹
					flag = true;
				}
			}
		} catch (Exception e) {
			log("O.java_删除指定文件夹下所有文件,@param path=" + path, e);
		}
		return flag;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 字符转换
	// ------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 将字符串转成unicode
	 * 
	 * @param str
	 *            待转字符串
	 * @return unicode字符串
	 */
	public static String convert(String str) {
		String unicode = new String();
		if (ckSt(str)) {
			char c;
			int i, j;
			String tmp;
			StringBuffer sb = new StringBuffer(1000);
			try {
				str = (str == null ? "" : str);
				sb.setLength(0);
				for (i = 0; i < str.length(); i++) {
					c = str.charAt(i);
					sb.append("\\u");
					j = (c >>> 8); // 取出高8位
					tmp = Integer.toHexString(j);
					if (tmp.length() == 1)
						sb.append("0");
					sb.append(tmp);
					j = (c & 0xFF); // 取出低8位
					tmp = Integer.toHexString(j);
					if (tmp.length() == 1)
						sb.append("0");
					sb.append(tmp);

				}
				unicode = new String(sb);
			} catch (Exception e) {
				log("O.java_将字符串转成unicode,@param str=" + str, e);
			}
		}
		return unicode;
	}

	/**
	 * 将unicode 转换成字符串
	 * 
	 * @param str
	 *            unicode码
	 * @return 普通字符串
	 */
	public static String revert(String str) {
		if (ckSt(str)) {
			StringBuffer sb = new StringBuffer(1000);
			try {
				str = (str == null ? "" : str);
				if (str.indexOf("\\u") == -1)// 如果不是unicode码则原样返回
					return str;

				for (int i = 0; i < str.length() - 6;) {
					String strTemp = str.substring(i, i + 6);
					String value = strTemp.substring(2);
					int c = 0;
					for (int j = 0; j < value.length(); j++) {
						char tempChar = value.charAt(j);
						int t = 0;
						switch (tempChar) {
						case 'a':
							t = 10;
							break;
						case 'b':
							t = 11;
							break;
						case 'c':
							t = 12;
							break;
						case 'd':
							t = 13;
							break;
						case 'e':
							t = 14;
							break;
						case 'f':
							t = 15;
							break;
						default:
							t = tempChar - 48;
							break;
						}

						c += t * ((int) Math.pow(16, (value.length() - j - 1)));
					}
					sb.append((char) c);
					i = i + 6;
				}
				str = sb.toString();
			} catch (Exception e) {
				log("O.java_将unicode转换成字符串,@param str=" + str + " , @return=" + sb, e);
			}
		}
		return str;
	}

	/**
	 * 中文乱码转换
	 * 
	 * @param string
	 * @return
	 */
	public static String servlet(String str) {
		String rst = "";
		try {
			rst = new String(str.getBytes("iso8859_1"), "GB2312");
		} catch (UnsupportedEncodingException e) {
			log("O.java_中文乱码转换,@param string=" + str + " , @return=" + rst, e);
		}
		return str;
	}

	/**
	 * 中文乱码 用于生成xls,word,文件时设置中文名称.
	 * 
	 * @param str
	 * @return
	 */
	public static String toUtf8String(String str) {
		StringBuffer sb = new StringBuffer();
		try {
			for (int i = 0; i < str.length(); i++) {
				char c = str.charAt(i);
				if (c >= 0 && c <= 255) {
					sb.append(c);
				} else {
					byte[] b;
					try {
						b = Character.toString(c).getBytes("utf-8");
					} catch (Exception ex) {
						System.out.println(ex);
						b = new byte[0];
					}
					for (int j = 0; j < b.length; j++) {
						int k = b[j];
						if (k < 0)
							k += 256;
						sb.append("%" + Integer.toHexString(k).toUpperCase());
					}
				}
			}
		} catch (Exception e) {
			log("O.java_中文乱码 用于生成xls,word,文件时设置中文名称.,@param str=" + str + " , @return=" + sb, e);
		}
		return sb.toString();
	}

	/**
	 * 生成没有-的uuid
	 * 
	 * @return
	 */
	public static String uuid() {
		UUID uuid = UUID.randomUUID();
		String str = uuid.toString();
		str = str.replace("-", "");
		return str;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 绝对路径
	// ------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 获取项目的绝对路径.
	 * 
	 * @return
	 */
	public String getRealPath() {
		String prefix = "";
		try {
			prefix = HttpUtil.getServletContext().getRealPath("/");
			if (StringUtil.isEmpty(prefix)) {
				prefix = getClass().getResource("/").getPath();
				int index = prefix.indexOf("WEB-INF");
				if (index == -1) {
					index = prefix.indexOf("bin");
				}
				prefix = prefix.substring(0, index);
				if (prefix.startsWith("zip")) {
					prefix = prefix.substring(4);
				} else if (prefix.startsWith("file")) {
					prefix = prefix.substring(6);
				} else if (prefix.startsWith("jar")) {
					prefix = prefix.substring(10);
				}
				prefix = prefix.replace("%20", " ");
			}
		} catch (Exception e) {
			prefix = getClass().getResource("/").getPath();
			int index = prefix.indexOf("WEB-INF");
			if (index == -1) {
				index = prefix.indexOf("bin");
			}
			prefix = prefix.substring(0, index);
			if (prefix.startsWith("zip")) {
				prefix = prefix.substring(4);
			} else if (prefix.startsWith("file")) {
				prefix = prefix.substring(6);
			} else if (prefix.startsWith("jar")) {
				prefix = prefix.substring(10);
			}
			prefix = prefix.replace("%20", " ");
			log("O.java_获取项目的绝对路径. @return=" + prefix, e);
		}
		return prefix;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// swf转换,用于在线预览
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 将Office文档转换为PDF. 运行该函数需要用到OpenOffice, OpenOffice下载地址为
	 * http://www.openoffice.org/
	 * 
	 * <pre>
	 * 方法示例:
	 * String sourcePath = "F:\\office\\source.doc";
	 * String destFile = "F:\\pdf\\dest.pdf";
	 * Converter.office2PDF(sourcePath, destFile);
	 * </pre>
	 * 
	 * @param sourceFile
	 *            源文件, 绝对路径. 可以是Office2003-2007全部格式的文档, Office2010的没测试. 包括.doc,
	 *            .docx, .xls, .xlsx, .ppt, .pptx等. 示例: F:\\office\\source.doc
	 * @param destFile
	 *            目标文件. 绝对路径. 示例: F:\\pdf\\dest.pdf
	 * @return 操作成功与否的提示信息. 如果返回 -1, 表示找不到源文件, 或url.properties配置错误; 如果返回 0,
	 *         则表示操作成功; 返回1, 则表示转换失败
	 */
	public static int office2PDF(String sourceFile, String destFile) {
		Process pro = null;
		OpenOfficeConnection connection = null;

		File inputFile = new File(sourceFile);
		if (!inputFile.exists())
			return -1;// 找不到源文件, 则返回-1

		// 如果目标路径不存在, 则新建该路径
		File outputFile = new File(destFile);
		if (!outputFile.getParentFile().exists())
			outputFile.getParentFile().mkdirs();

		// String OpenOffice_HOME = XmlUtil.conf("OPENOFFICEHOME");//
		// 这里是OpenOffice的安装目录,
		String OpenOffice_HOME = XmlUtil.conf("OPENOFFICEHOME");// 这里是OpenOffice的安装目录,
		// 在我的项目中,为了便于拓展接口,没有直接写成这个样子,但是这样是绝对没问题的
		// 如果从文件中读取的URL地址最后一个字符不是 '\'，则添加'\'

		if (OpenOffice_HOME.charAt(OpenOffice_HOME.length() - 1) != '\\')
			OpenOffice_HOME += "\\";

		try {

			// 启动OpenOffice的服务
			String command = OpenOffice_HOME + "program\\soffice.exe -headless -accept=\"socket,host="
					+ XmlUtil.conf("OPENOFFICEHOMEIP") + ",port=8100;urp;\"";
			pro = Runtime.getRuntime().exec(command);// 执行启动

			connection = new SocketOpenOfficeConnection(XmlUtil.conf("OPENOFFICEHOMEIP"), 8100);// 进行连接
			connection.connect();// 进行连接

			// convert
			DocumentConverter converter = new OpenOfficeDocumentConverter(connection);// 转换文件
			converter.convert(inputFile, outputFile);// 转换文件

			// 关闭OpenOffice服务的进程
			connection.disconnect();

			// 关闭
			pro.destroy();
			return 0;
		} catch (Exception e) {
			log("转换PDF出错,错误为:", e);
		} finally {

		}
		return 1;
	}

	/**
	 * 将pdf转换成swf.
	 * 
	 * @param pdfFilePath
	 *            pdf绝对文件路径
	 * @param swfFilePath
	 *            要转换成的swf文件的绝对路径
	 * @return
	 */
	public static int pdf2SWF(String pdfFilePath, String swfFilePath) {
		try {
			File inputFile = new File(pdfFilePath);
			if (!inputFile.exists()) {
				return -1;// 找不到源文件, 则返回-1
			}

			// 如果目标路径不存在, 则新建该路径
			File outputFile = new File(swfFilePath);
			if (!outputFile.getParentFile().exists()) {
				outputFile.getParentFile().mkdirs();
			}

			// String SWFTools_HOME = XmlUtil.conf("SWFTOOLSHOME");//
			// 这里是SWFTools的安装目录,
			String SWFTools_HOME = XmlUtil.conf("SWFTOOLSHOME");// 这里是SWFTools的安装目录,

			// 在我的项目中,为了便于拓展接口,没有直接写成这个样子,但是这样是绝对没问题的
			// 如果从文件中读取的URL地址最后一个字符不是 '\'，则添加'\'
			if (SWFTools_HOME.charAt(SWFTools_HOME.length() - 1) != '\\') {
				SWFTools_HOME += "\\";
			}
			// 启动pdf2swf的服务
			// String command = SWFTools_HOME + "pdf2swf.exe -t " + pdfFilePath
			// + " -o " + swfFilePath + " -T 9";
			String command = SWFTools_HOME + "pdf2swf.exe -t " + pdfFilePath + " -o " + swfFilePath + " -T 9";
			Process pro = Runtime.getRuntime().exec(command);
			pro.waitFor();
			// 关闭pdf2swf服务的进程
			pro.destroy();

			return 0;
		} catch (Exception e) {
			log("O.java_将pdf转换成swf. @pdfFilePath=" + pdfFilePath + ", @swfFilePath=" + swfFilePath, e);
			return -1;
		}
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 文件
	// ------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 文件拷贝
	 * 
	 * @param file
	 *            文件 Hello world.doc
	 * @param path
	 *            地址 D:\\MyWorld.doc
	 * @return
	 */
	public static Boolean saveFile(File file, String path) {
		Boolean bn = true;
		try {
			int length = 2097152;
			FileInputStream in = new FileInputStream(file);
			FileOutputStream out = new FileOutputStream(new File(path));
			FileChannel inC = in.getChannel();
			FileChannel outC = out.getChannel();
			ByteBuffer b = null;
			if (inC.position() == inC.size()) {
				inC.close();
				outC.close();
			}
			if ((inC.size() - inC.position()) < length) {
				length = (int) (inC.size() - inC.position());
			} else
				length = 2097152;
			b = ByteBuffer.allocateDirect(length);
			inC.read(b);
			b.flip();
			outC.write(b);
			outC.force(false);
			outC.close();
			inC.close();
			in.close();
			out.close();
		} catch (Exception e) {
			bn = false;
			e.printStackTrace();
			log("O.java_文件上传. @file=" + file + ", @path=" + path, e);
		}
		return bn;
	}

	/**
	 * 将二进制码转换成文件保存至文件夹
	 * 
	 * @param data
	 *            数据
	 * @param filePath
	 *            所保存的文件地址.D://hello.doc
	 * @return
	 */
	public static void saveFile(byte[] data, String filePath) {
		try {
			File myFile = new File(filePath);
			if (!myFile.exists()) {
				myFile.createNewFile();
			}

			if (data != null && data.length > 0) {
				FileOutputStream out = new FileOutputStream(new File(filePath));// 指定要写入的文件
				out.write(data, 0, data.length);
				out.close();// 关闭输入输出流
			}
		} catch (IOException e) {
			log("O.java_将二进制码转换成文件保存至文件夹. @filePath=" + filePath, e);
		}

	}

	/**
	 * 创建文件夹
	 * 
	 * @param path
	 * @return
	 */
	public static boolean creatFolder(String path) {
		boolean bn = true;
		File file = new File(path);
		if (!file.exists()) {
			file.mkdirs();
		}
		return bn;
	}

	/**
	 * 将文件转换为byte[]类型
	 * 
	 * @param file
	 * @return
	 */
	public static byte[] cnBlog(File file) {
		byte[] content = null;
		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte[] b = new byte[1024 * 1024];
			int n;
			while ((n = fis.read(b)) != -1) {
				out.write(b, 0, n);
			}
			fis.close();
			out.close();
			content = out.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return content;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 阿拉伯数字转换成中文数字,以及金额转换.
	// ------------------------------------------------------------------------------------------------------------------------------------
	public static String[] chineseDigits = new String[] { "零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖" };

	/**
	 * 把金额转换为汉字表示的数量，小数点后四舍五入保留两位
	 * 
	 * @param amount
	 *            传入的数字
	 * @return
	 */
	public static String amountToChinese(Object deamount) {
		String chineseStr = "";
		Double amount = cnDe(deamount);

		try {
			if (amount > 99999999999999.99 || amount < -99999999999999.99)
				throw new IllegalArgumentException("参数值超出允许范围 (-99999999999999.99 ～ 99999999999999.99)！");

			boolean negative = false;
			if (amount < 0) {
				negative = true;
				amount = amount * (-1);
			}

			long temp = Math.round(amount * 100);
			int numFen = (int) (temp % 10); // 分
			temp = temp / 10;
			int numJiao = (int) (temp % 10); // 角
			temp = temp / 10;
			// temp 目前是金额的整数部分

			int[] parts = new int[20]; // 其中的元素是把原来金额整数部分分割为值在 0~9999 之间的数的各个部分
			int numParts = 0; // 记录把原来金额整数部分分割为了几个部分（每部分都在 0~9999 之间）
			for (int i = 0;; i++) {
				if (temp == 0)
					break;
				int part = (int) (temp % 10000);
				parts[i] = part;
				numParts++;
				temp = temp / 10000;
			}

			boolean beforeWanIsZero = true; // 标志“万”下面一级是不是 0

			for (int i = 0; i < numParts; i++) {

				String partChinese = partTranslate(parts[i]);
				if (i % 2 == 0) {
					if ("".equals(partChinese))
						beforeWanIsZero = true;
					else
						beforeWanIsZero = false;
				}

				if (i != 0) {
					if (i % 2 == 0)
						chineseStr = "亿" + chineseStr;
					else {
						if ("".equals(partChinese) && !beforeWanIsZero) // 如果“万”对应的
							// part 为
							// 0，而“万”下面一级不为
							// 0，则不加“万”，而加“零”
							chineseStr = "零" + chineseStr;
						else {
							if (parts[i - 1] < 1000 && parts[i - 1] > 0) // 如果"万"的部分不为
								// 0,
								// 而"万"前面的部分小于
								// 1000
								// 大于 0，
								// 则万后面应该跟“零”
								chineseStr = "零" + chineseStr;
							chineseStr = "万" + chineseStr;
						}
					}
				}
				chineseStr = partChinese + chineseStr;
			}

			if ("".equals(chineseStr)) // 整数部分为 0, 则表达为"零元"
				chineseStr = chineseDigits[0];
			else if (negative) // 整数部分不为 0, 并且原金额为负数
				chineseStr = "负" + chineseStr;

			chineseStr = chineseStr + "元";

			if (numFen == 0 && numJiao == 0) {
				chineseStr = chineseStr + "整";
			} else if (numFen == 0) { // 0 分，角数不为 0
				chineseStr = chineseStr + chineseDigits[numJiao] + "角";
			} else { // “分”数不为 0
				if (numJiao == 0)
					chineseStr = chineseStr + "零" + chineseDigits[numFen] + "分";
				else
					chineseStr = chineseStr + chineseDigits[numJiao] + "角" + chineseDigits[numFen] + "分";
			}
		} catch (Exception e) {
			log("O.java_把金额转换为汉字表示的数量,小数点后四舍五入保留两位 @deamount=" + deamount + " @return " + chineseStr, e);
		}

		return chineseStr;

	}

	/**
	 * 把一个 0~9999 之间的整数转换为汉字的字符串，如果是 0 则返回 ""
	 * 
	 * @param amountPart
	 * @return
	 */
	private static String partTranslate(int amountPart) {
		String chineseStr = "";

		try {
			if (amountPart < 0 || amountPart > 10000) {
				throw new IllegalArgumentException("参数必须是大于等于 0，小于 10000 的整数！");
			}

			String[] units = new String[] { "", "拾", "佰", "仟" };

			int temp = amountPart;

			String amountStr = new Integer(amountPart).toString();
			int amountStrLength = amountStr.length();
			boolean lastIsZero = true; // 在从低位往高位循环时，记录上一位数字是不是 0

			for (int i = 0; i < amountStrLength; i++) {
				if (temp == 0) // 高位已无数据
					break;
				int digit = temp % 10;
				if (digit == 0) { // 取到的数字为 0
					if (!lastIsZero) // 前一个数字不是 0，则在当前汉字串前加“零”字;
						chineseStr = "零" + chineseStr;
					lastIsZero = true;
				} else { // 取到的数字不是 0
					chineseStr = chineseDigits[digit] + units[i] + chineseStr;
					lastIsZero = false;
				}
				temp = temp / 10;
			}
		} catch (Exception e) {
			log("O.java_把一个 0~9999 之间的整数转换为汉字的字符串  @amountPart=" + amountPart + " @return " + chineseStr, e);
		}

		return chineseStr;
	}

	/**
	 * 将数字转换成货币格式1,234,567,890
	 * 
	 * @param money
	 * @return
	 */
	public static String formatMoney(Object money) {
		NumberFormat format = NumberFormat.getInstance(Locale.CHINA);
		return format.format(money);
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// json字符串转换
	// ------------------------------------------------------------------------------------------------------------------------------------
	private static final ObjectMapper objectMapper = new ObjectMapper();

	public ObjectMapper getInstance() {
		return objectMapper;
	}

	/**
	 * 使用Jackson 数据绑定 将对象转换为 json字符串
	 * 
	 * 还可以 直接使用 JsonUtils.getInstance().writeValueAsString(Object obj)方式
	 * 
	 * @param obj
	 * @return
	 */
	public String toJsonString(Object obj) {
		try {
			String rst = objectMapper.writeValueAsString(obj);
			return rst;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * json字符串转化为 JavaBean
	 * 
	 * 还可以直接JsonUtils.getInstance().readValue(String content,Class
	 * valueType)用这种方式
	 * 
	 * @param <T>
	 * @param content
	 *            JSON String
	 * @param valueType
	 *            Class
	 * @return
	 */
	public static <T> T toJavaBean(String content, Class<T> valueType) throws Exception {
		try {
			return objectMapper.readValue(content, valueType);
		} catch (JsonParseException e) {
			logger.error("json字符串转化为 javabean失败" + e.toString());
		} catch (JsonMappingException e) {
			logger.error("json字符串转化为 javabean失败" + e.toString());
		} catch (IOException e) {
			logger.error("json字符串转化为 javabean失败" + e.toString());
		}
		return null;
	}

	/**
	 * json字符串转化为list<T>
	 * 
	 * 还可以 直接使用 JsonUtils.getInstance().readValue(String content, new
	 * TypeReference<List<T>>(){})方式
	 * 
	 * @param <T>
	 * @param content
	 *            JSON String
	 * @param valueType
	 *            new TypeReference<List<T>>(){}
	 * @return
	 * @throws IOException
	 */
	public static <T> List<T> toJavaBeanList(String content, TypeReference<List<T>> typeReference) throws IOException {
		try {
			return objectMapper.readValue(content, typeReference);
		} catch (JsonParseException e) {
			logger.error("json字符串转化为 list失败,原因:" + e.toString());
			throw new RuntimeException("json字符串转化为 list失败");
		} catch (JsonMappingException e) {
			logger.error("json字符串转化为 list失败,原因" + e.toString());
			throw new JsonMappingException("json字符串转化为 list失败");
		} catch (IOException e) {
			logger.error("json字符串转化为 list失败,原因" + e.toString());
			throw new IOException("json字符串转化为 list失败");
		}
	}

	/**
	 * json中获得一项
	 * 
	 * @return
	 */
	public static String getItem(String item, String json) {
		try {
			org.json.JSONObject jsonObj = new org.json.JSONObject(json);
			String returnStr = jsonObj.getString(item);
			if ("[]".equals(returnStr)) {
				return null;
			}
			return returnStr;
		} catch (Exception e) {
			return null;
		}

	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 阿拉伯数字转换成中文数字,以及金额转换.
	// ------------------------------------------------------------------------------------------------------------------------------------
	/**
	 * 将字符串中的中文转化为拼音,其他字符不变
	 * 
	 * @param inputString
	 * @return
	 */
	public static String getPingYin(String inputString) {
		HanyuPinyinOutputFormat format = new HanyuPinyinOutputFormat();
		format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		format.setVCharType(HanyuPinyinVCharType.WITH_V);

		char[] input = inputString.trim().toCharArray();
		String output = "";

		try {
			for (int i = 0; i < input.length; i++) {
				if (java.lang.Character.toString(input[i]).matches("[\\u4E00-\\u9FA5]+")) {
					String[] temp = PinyinHelper.toHanyuPinyinStringArray(input[i], format);
					output += temp[0];
				} else
					output += java.lang.Character.toString(input[i]);
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			log("O.java_将字符串中的中文转化为拼音,其他字符不变  @inputString=" + inputString + " @return " + output, e);
		}
		return output;
	}

	// ------------------------------------------------------------------------------------------------------------------------------------
	// 数据库操作方发.
	// ------------------------------------------------------------------------------------------------------------------------------------

	/**
	 * 保存数据库
	 * 
	 * @param args
	 *            保存的路径+文件名称
	 */
	public static void saveMysql(String filePath) {
		List conString = XmlUtil.getHibernateCfgXMl();
		String[] con = conString.get(1).toString().split("/");
		String[] conIPandPort = con[2].split(":");

		String cmd = "mysqldump.exe --no-defaults --hex-blob --add-drop-table -h " + conIPandPort[0]

		+ " -P " + conIPandPort[1]

		+ " -u " + conString.get(2).toString()

		+ " -p" + conString.get(3).toString()

		+ "  --default-character-set=utf8 "

		+ con[3]

		+ " > " + filePath;
		cmdMysql(cmd);

	}

	/**
	 * 恢复数据库
	 * 
	 * @param args
	 *            保存的路径+文件名称
	 */
	public static void loadMysql(String filePath) {
		List conString = XmlUtil.getHibernateCfgXMl();
		String[] con = conString.get(1).toString().split("/");
		String[] conIPandPort = con[2].split(":");

		String cmd = "mysql.exe -h " + conIPandPort[0]

		+ " -P " + conIPandPort[1]

		+ " -u " + conString.get(2).toString()

		+ " -p" + conString.get(3).toString()

		+ " --default-character-set=utf8 "

		+ con[3]

		+ " < " + filePath;

		cmdMysql(cmd);
	}

	/**
	 * 初始化数据库
	 * 
	 * @param args
	 *            保存的路径+文件名称
	 */
	public static void initMysql(String filePath) {

		loadMysql(filePath);

	}

	public static void cmdMysql(String cmd) {
		try {
			Runtime rt = Runtime.getRuntime();

			rt.exec("cmd /c \"" + cmd + "\"");
			// 设置导出编码为utf8。这里必须是utf8

			// 把进程执行中的控制台输出信息写入.sql文件，即生成了备份文件。注：如果不对控制台信息进行读出，则会导致进程堵塞无法运行
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 汉字转拼音的方法
	 * 
	 * @param name
	 *            汉字
	 * @return 拼音
	 */
	public static String cnpy(String name) {
		String pinyinName = "";
		char[] nameChar = name.toCharArray();
		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		for (int i = 0; i < nameChar.length; i++) {
			if (nameChar[i] > 128) {
				try {
					pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0];
				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			}
		}
		return pinyinName;
	}

	public static String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 拼音转换
	 */
	public static String cnpykt(String cnpyve) {
		String rst = "";
		try {
			StringBuffer sb = new StringBuffer();
			if (ckSt(cnpyve)) {
				Pattern p_str = Pattern.compile("[\\u4e00-\\u9fa5]+");
				for (int i = 0; i < cnpyve.length(); i++) {
					String name = cnpyve.substring(i, i + 1);
					Matcher m = p_str.matcher(name);
					if (m.find() && m.group(0).equals(name)) {
						name = cnpy(name).substring(0, 1);
					}
					sb.append(name);
				}
				rst = cnSt(sb);
			}

		} catch (Exception e) {
			rst = "E";
			log("汉字转换拼音失败,错误为:", e);
		}
		return rst;
	}

	// **************************************
	// 判断List是否为空，不
	// ***************************************
	/**
	 * 判断List是否为空
	 * 
	 * @param list
	 * @return 不为空返回：true；为空返回false
	 */
	public static boolean listIsEmpty(List<?> list) {
		if (null != list && 0 < list.size() && !list.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 将字符串转化成数组
	 * 
	 * @param values
	 * @return
	 */
	public static int[] getIntValues(String values) {
		int[] endValue = null;
		String[] nextValue = null;
		if (O.ckSt(values)) {
			nextValue = values.split(",");
			endValue = new int[nextValue.length];
			for (int i = 0; i < nextValue.length; i++) {
				endValue[i] = Integer.valueOf(nextValue[i]);
			}
		}
		return endValue;
	}

	/**
	 * 去除特殊符号
	 * 
	 * @param str
	 * @return
	 */
	public static String removeSymbols(String str) {
		if (!O.ckSt(str)) {
			return null;
		}
		if (str.contains("　")) {
			str = str.replaceAll("　", "");
		} else if (str.contains(" ")) {
			str = str.replaceAll(" ", "");
		} else if (str.contains("\n")) {
			str = str.replaceAll("\n", "");
		} else if (str.contains("\r")) {
			str = str.replaceAll("\r", "");
		}

		return str;
	}
}
